<template>
  <div>
    <ul :class="'level' + level" class="tree-container">
      <li
        v-for="(item, Index) in menuData"
        :key="item.value - item.permission_type"
        :class="
          !item.children || item.children.length == 0
            ? 'level' + item.level + ' dis2'
            : 'level' + item.level
        "
        class=""
      >
        <div :class="'level' + item.title" class="tree-node-title">
          <Checkbox
            :indeterminate="item.isIndeterminate"
            v-model="item.checked"
            :disabled="item.disabled==1"
            @click.native="nodeClick(item, Index)"
          >
            {{ item.title }}
          </Checkbox>
        </div>
        <div
          :class="'level' + item.level"
          class="tree-childnode-container"
          v-if="item.children && item.children.length > 0"
        >
          <CheckBox
            :menuData="item.children"
            :roledata="roledata"
            :level="item.level"
            :disabled="item.disabled==1"
          ></CheckBox>
        </div>
      </li>
    </ul>
  </div>
</template>
  
  <script>
import { mapActions } from "vuex";
export default {
  name: "CheckBox",
  props: {
    menuData: {
      type: Array,
      default: function () {
        return [];
      },
    },
    roledata: {
      type: Array,
      default: function () {
        return [];
      },
    },
    level: {
      type: Number,
      default: null,
    },
  },
  data() {
    return {
      action_ids: [], // 动作
      menu_ids: [], // 父级
      checkedVal: [],
      menuList: [],
      choseAll: false,
    };
  },
  created() {},
  mounted() {},
  methods: {
    ...mapActions("power/power", ["menuIdsAsync", "actionIdsAsync"]),
    nodeClick(node, index) {
      if(node.disabled==1){
        return;
      }
      this.action_ids = []; // 动作
      this.menu_ids = []; // 父级
      // 通过isChecked判断是否为选中状态：1-选中；0-未选中。这个字段是后端接口返回的
      if (node.checked === true) {
        node.checked = false;
        node.isIndeterminate = false;
      } else {
        node.checked = true;
        node.isIndeterminate = false;
      }
      // 个人理解：组件每次递归调用会生成一个实例，this指向这个实例，这些实例相互独立的，所以每次的this都不一样，具体可以控制台打印看下。
      this.refreshAllParentNodes(this); // 设置父级状态
      this.refreshAllSonNodes(this.$el.children[0]['children'][index], node.checked, node); // 根据当前点击层级的状态设置自己所有子级的状态
      this.refreshgrops(this.roledata);
      this.menuIdsAsync(this.menu_ids);
      this.actionIdsAsync(this.action_ids);
    },
    refreshAllSonNodes(node, status, item) {
      if (node && item.children) {
        item.children.map((meunItem, j) => {
          if(meunItem.disabled==1){
            return;
          }
          meunItem.checked = status;
          meunItem.isIndeterminate = false;
          this.refreshAllSonNodes([], status, meunItem);
        });
      }
    },
    refreshAllParentNodes(node) {
      if (node) {
        var status = 0;
        var nullCount = 0;
        var fullCount = 0;
        var isIndeterminate;
        var isIndeterminateCount = 0;
        
        if (node.menuData && node.$parent.menuData) {
          node.menuData.map((meunItem, j) => {
            if (typeof meunItem.checked === "undefined") {
              nullCount++;
            } else if (meunItem.checked === false) {
              nullCount++;
            } else if (meunItem.checked === true) {
              fullCount++;
            }
            if (meunItem.isIndeterminate === true) {
              isIndeterminateCount++;
            }
          });
          if (fullCount === node.menuData.length) {
            // 该状态说明当前点击层级和兄弟层级都没选中，所以父级也是未选中状态
            status = true;
          } else {
            // 该状态说明当前点击层级和兄弟层级只要有一个选中，父级也是选中状态
            status = false;
          }
          if (
            (fullCount > 0 && fullCount < node.menuData.length) ||
            isIndeterminateCount > 0
          ) {
            isIndeterminate = true;
          } else {
            isIndeterminate = false;
          }
          node.$parent.menuData.map((child) => {
            node.menuData.map((meunItem, j) => {
              if (child.value === meunItem.pid) {
                // 根据父级id和子级的parentId是否相等，来确定当前点击的层级的父级是哪一个
                child.checked = status;
                child.isIndeterminate = isIndeterminate;
              }
            });
          });
        }
        // 递归计算父级
        this.refreshAllParentNodes(node.$parent);
      }
    },
    // 接收值处理自己想要的数据
    refreshgrops(item) {
      item.forEach((el) => {
        if (el.checked === true && el.permission_type === 2) {
          this.action_ids.push(el.value);
        } else if (
          (el.checked == true || el.isIndeterminate) &&
          el.permission_type === 1
        ) {
          this.menu_ids.push(el.value);
        }
        if (el.children) {
          this.refreshgrops(el.children);
        }
      });
    }
  },
};
</script>
  <style lang="less" scoped>
@borderColor: #ebeef5;
.level1,
.level2 {
  // border: 1px solid #ebeef5;
}
.tree-node-title {
  line-height: 30px;
}
.tree-container {
  // border: 1px solid #ebeef5;

  width: 100%;
  padding: 0;
  li {
    list-style-type: none;
  }
  & > .level1 {
    border: 1px solid #ebeef5;
    padding: 8px;
  }
  &.level3 {
    display: flex;
    flex-wrap: wrap;

    & > .level4 {
      //   width: 25%;
      padding: 0 20px 0 40px;
      .level5 {
        // background:#f7ffff;
        // width: 25%;
        padding: 0 20px 0 30px;
      }
    }
  }
  & > .level2 {
    // display: flex;
    padding-left: 20px;
    align-items: center;
    border: 1px solid @borderColor;
    line-height: 30px;
    .tree-node-title {
      // width: 200px;
      padding: 0 10px;
      flex-shrink: 0;
      line-height: 30px;
      &.level2 {
        width: 200px;
        text-align: center;
      }
    }
  }
  .level3 {
    .level3 + .level3 {
      border-top: 1px solid @borderColor;
    }
  }

  .tree-node-title {
    &.level3 {
      background-color: #f2f2f2;
      width: 100%;
      padding: 0 20px;
    }

    &.level1 {
      padding: 20px 0;
    }
  }

  .level2 + .level2 {
    border-top: none;
  }

  .tree-childnode-container {
    width: 100%;
    border: none;
    &.level2 {
      // border-left: 1px solid @borderColor;
      padding-left: 20px;
    }
  }
  .dis2 {
    display: inline-block;
    border: none;
  }
  input {
    margin-right: 5px;
  }

  label {
    cursor: pointer;
  }
}
</style>
  